@@ -31,6 +31,19 @@ import (
3131 "3e8.eu/go/dsl/internal/httpdigest"
3232)
3333
34+ type httpError struct {
35+ Err error
36+ StatusCode int
37+ }
38+
39+ func (e * httpError ) Error () string {
40+ return e .Err .Error ()
41+ }
42+
43+ func (e * httpError ) Unwrap () error {
44+ return e .Err
45+ }
46+
3447type session struct {
3548 host string
3649 username string
@@ -227,7 +240,10 @@ func (s *session) get(path string) ([]byte, error) {
227240 defer resp .Body .Close ()
228241
229242 if resp .StatusCode != 200 {
230- err = fmt .Errorf ("request for %s failed with status %d" , path , resp .StatusCode )
243+ err = & httpError {
244+ Err : fmt .Errorf ("request for %s failed with status %d" , path , resp .StatusCode ),
245+ StatusCode : resp .StatusCode ,
246+ }
231247
232248 if resp .StatusCode == 303 {
233249 return nil , & dsl.ConnectionError {Err : err }
@@ -247,7 +263,10 @@ func (s *session) postForm(path string, data url.Values) ([]byte, error) {
247263 defer resp .Body .Close ()
248264
249265 if resp .StatusCode != 200 {
250- err = fmt .Errorf ("request for %s failed with status %d" , path , resp .StatusCode )
266+ err = & httpError {
267+ Err : fmt .Errorf ("request for %s failed with status %d" , path , resp .StatusCode ),
268+ StatusCode : resp .StatusCode ,
269+ }
251270
252271 if resp .StatusCode == 303 {
253272 return nil , & dsl.ConnectionError {Err : err }
@@ -272,12 +291,16 @@ func (s *session) loadPost(path string, data url.Values) (string, error) {
272291 return string (body ), err
273292}
274293
275- func (s * session ) loadSupportData ( ) (string , error ) {
294+ func (s * session ) loadSupportDataInternal ( tryDiagnosisData bool ) (string , error ) {
276295 // this needs to use multipart/form-data and the order of the fields is important
277296 var body bytes.Buffer
278297 mpart := multipart .NewWriter (& body )
279298 mpart .WriteField ("sid" , s .sid )
280- mpart .WriteField ("DiagnosisData" , "" )
299+ if tryDiagnosisData {
300+ mpart .WriteField ("DiagnosisData" , "" )
301+ } else {
302+ mpart .WriteField ("SupportData" , "" )
303+ }
281304
282305 req , err := http .NewRequest (http .MethodPost , s .host + "/cgi-bin/firmwarecfg" , & body )
283306 if err != nil {
@@ -293,7 +316,10 @@ func (s *session) loadSupportData() (string, error) {
293316 defer resp .Body .Close ()
294317
295318 if resp .StatusCode != 200 {
296- err = fmt .Errorf ("request for support data failed with status %d" , resp .StatusCode )
319+ err = & httpError {
320+ Err : fmt .Errorf ("request for support data failed with status %d" , resp .StatusCode ),
321+ StatusCode : resp .StatusCode ,
322+ }
297323
298324 if resp .StatusCode == 303 {
299325 return "" , & dsl.ConnectionError {Err : err }
@@ -309,23 +335,46 @@ func (s *session) loadSupportData() (string, error) {
309335 for scanner .Scan () {
310336 line := scanner .Text ()
311337
312- if ! foundBeginSection && strings .HasPrefix (line , "#### BEGIN SECTION DSLManager_port" ) {
313- foundBeginSection = true
338+ if strings .HasPrefix (line , "<!DOCTYPE" ) {
339+ resp .Body .Close ()
340+
341+ if tryDiagnosisData {
342+ return s .loadSupportDataInternal (false )
343+ } else {
344+ return "" , fmt .Errorf ("got HTML response instead of support data" )
345+ }
346+ }
347+
348+ if ! foundBeginSection {
349+ if (strings .HasPrefix (line , "#### BEGIN SECTION DSLManager_port" ) &&
350+ ! strings .HasPrefix (line , "#### BEGIN SECTION DSLManager_port_undependent" )) ||
351+ strings .HasPrefix (line , "DSL Overview" ) {
352+ foundBeginSection = true
353+ }
314354 }
315355
316356 if foundBeginSection {
357+ if strings .HasPrefix (line , "DSL Configs" ) {
358+ resp .Body .Close ()
359+ break
360+ }
361+
317362 fmt .Fprintln (& b , line )
318- }
319363
320- if foundBeginSection && strings .HasPrefix (line , "#### END SECTION DSLManager_port" ) {
321- resp .Body .Close ()
322- break
364+ if strings .HasPrefix (line , "#### END SECTION DSLManager_port" ) {
365+ resp .Body .Close ()
366+ break
367+ }
323368 }
324369 }
325370
326371 return b .String (), scanner .Err ()
327372}
328373
374+ func (s * session ) loadSupportData () (string , error ) {
375+ return s .loadSupportDataInternal (true )
376+ }
377+
329378func (s * session ) getHostWithoutPort () string {
330379 bracketIndex := strings .LastIndexByte (s .host , ']' )
331380 if bracketIndex != - 1 {
@@ -399,7 +448,10 @@ func (s *session) loadTR064(path, serviceType, action string) (string, error) {
399448 }
400449
401450 if resp .StatusCode != 200 {
402- err = fmt .Errorf ("request for %s failed with status %d - make sure that TR-064 (access for apps) is enabled" , soapAction , resp .StatusCode )
451+ err = & httpError {
452+ Err : fmt .Errorf ("request for %s failed with status %d - make sure that TR-064 (access for apps) is enabled" , soapAction , resp .StatusCode ),
453+ StatusCode : resp .StatusCode ,
454+ }
403455
404456 if resp .StatusCode == 401 {
405457 return "" , & dsl.ConnectionError {Err : err }
0 commit comments