github.com/chnsz/golangsdk@v0.0.0-20240506093406-85a3fbfa605b/openstack/obs/http.go (about) 1 // Copyright 2019 Huawei Technologies Co.,Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use 3 // this file except in compliance with the License. You may obtain a copy of the 4 // License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software distributed 9 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 10 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 // specific language governing permissions and limitations under the License. 12 13 package obs 14 15 import ( 16 "bytes" 17 "errors" 18 "fmt" 19 "io" 20 "io/ioutil" 21 "math/rand" 22 "net" 23 "net/http" 24 "net/url" 25 "os" 26 "strconv" 27 "strings" 28 "time" 29 ) 30 31 func prepareHeaders(headers map[string][]string, meta bool, isObs bool) map[string][]string { 32 _headers := make(map[string][]string, len(headers)) 33 for key, value := range headers { 34 key = strings.TrimSpace(key) 35 if key == "" { 36 continue 37 } 38 _key := strings.ToLower(key) 39 if _, ok := allowedRequestHTTPHeaderMetadataNames[_key]; !ok && !strings.HasPrefix(key, HEADER_PREFIX) && !strings.HasPrefix(key, HEADER_PREFIX_OBS) { 40 if !meta { 41 continue 42 } 43 if !isObs { 44 _key = HEADER_PREFIX_META + _key 45 } else { 46 _key = HEADER_PREFIX_META_OBS + _key 47 } 48 } else { 49 _key = key 50 } 51 _headers[_key] = value 52 } 53 return _headers 54 } 55 56 func (obsClient ObsClient) checkParamsWithBucketName(bucketName string) bool { 57 return strings.TrimSpace(bucketName) == "" && !obsClient.conf.cname 58 } 59 60 func (obsClient ObsClient) checkParamsWithObjectKey(objectKey string) bool { 61 return strings.TrimSpace(objectKey) == "" 62 } 63 64 func (obsClient ObsClient) doActionWithoutBucket(action, method string, input ISerializable, output IBaseModel, extensions []extensionOptions) error { 65 return obsClient.doAction(action, method, "", "", input, output, true, true, extensions, nil) 66 } 67 68 func (obsClient ObsClient) doActionWithBucketV2(action, method, bucketName string, input ISerializable, output IBaseModel, extensions []extensionOptions) error { 69 if obsClient.checkParamsWithBucketName(bucketName) { 70 return errors.New("Bucket is empty") 71 } 72 return obsClient.doAction(action, method, bucketName, "", input, output, false, true, extensions, nil) 73 } 74 75 func (obsClient ObsClient) doActionWithBucket(action, method, bucketName string, input ISerializable, output IBaseModel, extensions []extensionOptions) error { 76 if obsClient.checkParamsWithBucketName(bucketName) { 77 return errors.New("Bucket is empty") 78 } 79 return obsClient.doAction(action, method, bucketName, "", input, output, true, true, extensions, nil) 80 } 81 82 func (obsClient ObsClient) doActionWithBucketAndKey(action, method, bucketName, objectKey string, input ISerializable, output IBaseModel, extensions []extensionOptions) error { 83 if obsClient.checkParamsWithBucketName(bucketName) { 84 return errors.New("Bucket is empty") 85 } 86 if obsClient.checkParamsWithObjectKey(objectKey) { 87 return errors.New("Key is empty") 88 } 89 return obsClient.doAction(action, method, bucketName, objectKey, input, output, true, true, extensions, nil) 90 } 91 92 func (obsClient ObsClient) doActionWithBucketAndKeyWithProgress(action, method, bucketName, objectKey string, input ISerializable, output IBaseModel, extensions []extensionOptions, listener ProgressListener) error { 93 if obsClient.checkParamsWithBucketName(bucketName) { 94 return errors.New("Bucket is empty") 95 } 96 if obsClient.checkParamsWithObjectKey(objectKey) { 97 return errors.New("Key is empty") 98 } 99 return obsClient.doAction(action, method, bucketName, objectKey, input, output, true, true, extensions, listener) 100 } 101 102 func (obsClient ObsClient) doActionWithBucketAndKeyV2(action, method, bucketName, objectKey string, input ISerializable, output IBaseModel, extensions []extensionOptions) error { 103 if obsClient.checkParamsWithBucketName(bucketName) { 104 return errors.New("Bucket is empty") 105 } 106 if obsClient.checkParamsWithObjectKey(objectKey) { 107 return errors.New("Key is empty") 108 } 109 return obsClient.doAction(action, method, bucketName, objectKey, input, output, false, true, extensions, nil) 110 } 111 112 func (obsClient ObsClient) doActionWithBucketAndKeyUnRepeatable(action, method, bucketName, objectKey string, input ISerializable, output IBaseModel, extensions []extensionOptions) error { 113 if obsClient.checkParamsWithBucketName(bucketName) { 114 return errors.New("Bucket is empty") 115 } 116 if obsClient.checkParamsWithObjectKey(objectKey) { 117 return errors.New("Key is empty") 118 } 119 return obsClient.doAction(action, method, bucketName, objectKey, input, output, true, false, extensions, nil) 120 } 121 122 func (obsClient ObsClient) doActionWithBucketAndKeyUnRepeatableWithProgress(action, method, bucketName, objectKey string, input ISerializable, output IBaseModel, extensions []extensionOptions, listener ProgressListener) error { 123 if obsClient.checkParamsWithBucketName(bucketName) { 124 return errors.New("Bucket is empty") 125 } 126 if obsClient.checkParamsWithObjectKey(objectKey) { 127 return errors.New("Key is empty") 128 } 129 return obsClient.doAction(action, method, bucketName, objectKey, input, output, true, false, extensions, listener) 130 } 131 132 func (obsClient ObsClient) doAction(action, method, bucketName, objectKey string, input ISerializable, output IBaseModel, xmlResult bool, repeatable bool, extensions []extensionOptions, listener ProgressListener) error { 133 134 var resp *http.Response 135 var respError error 136 doLog(LEVEL_INFO, "Enter method %s...", action) 137 start := GetCurrentTimestamp() 138 isObs := obsClient.conf.signature == SignatureObs 139 140 params, headers, data, err := input.trans(isObs) 141 if err != nil { 142 return err 143 } 144 145 if params == nil { 146 params = make(map[string]string) 147 } 148 149 if headers == nil { 150 headers = make(map[string][]string) 151 } 152 153 for _, extension := range extensions { 154 if extensionHeader, ok := extension.(extensionHeaders); ok { 155 if _err := extensionHeader(headers, isObs); err != nil { 156 doLog(LEVEL_INFO, fmt.Sprintf("set header with error: %v", _err)) 157 } 158 } else { 159 doLog(LEVEL_INFO, "Unsupported extensionOptions") 160 } 161 } 162 163 resp, respError = obsClient.doHTTPRequest(method, bucketName, objectKey, params, headers, data, repeatable, listener) 164 165 if respError == nil && output != nil { 166 respError = HandleHttpResponse(action, headers, output, resp, xmlResult, isObs) 167 } else { 168 doLog(LEVEL_WARN, "Do http request with error: %v", respError) 169 } 170 171 if isDebugLogEnabled() { 172 doLog(LEVEL_DEBUG, "End method %s, obsclient cost %d ms", action, (GetCurrentTimestamp() - start)) 173 } 174 175 return respError 176 } 177 178 func (obsClient ObsClient) doHTTPRequest(method, bucketName, objectKey string, params map[string]string, 179 headers map[string][]string, data interface{}, repeatable bool, listener ProgressListener) (*http.Response, error) { 180 return obsClient.doHTTP(method, bucketName, objectKey, params, prepareHeaders(headers, false, obsClient.conf.signature == SignatureObs), data, repeatable, listener) 181 } 182 183 func prepareAgentHeader(clientUserAgent string) string { 184 userAgent := USER_AGENT 185 if clientUserAgent != "" { 186 userAgent = clientUserAgent 187 } 188 return userAgent 189 } 190 191 func (obsClient ObsClient) getSignedURLResponse(action string, output IBaseModel, xmlResult bool, resp *http.Response, err error, start int64) (respError error) { 192 var msg interface{} 193 isObs := obsClient.conf.signature == SignatureObs 194 if err != nil { 195 respError = err 196 resp = nil 197 } else { 198 doLog(LEVEL_DEBUG, "Response headers: %s", logResponseHeader(resp.Header)) 199 if resp.StatusCode >= 300 { 200 respError = ParseResponseToObsError(resp, isObs) 201 msg = resp.Status 202 resp = nil 203 } else { 204 if output != nil { 205 respError = ParseResponseToBaseModel(resp, output, xmlResult, isObs) 206 } 207 if respError != nil { 208 doLog(LEVEL_WARN, "Parse response to BaseModel with error: %v", respError) 209 } 210 } 211 } 212 213 if msg != nil { 214 doLog(LEVEL_ERROR, "Failed to send request with reason:%v", msg) 215 } 216 217 if isDebugLogEnabled() { 218 doLog(LEVEL_DEBUG, "End method %s, obsclient cost %d ms", action, (GetCurrentTimestamp() - start)) 219 } 220 return 221 } 222 223 func (obsClient ObsClient) doHTTPWithSignedURL(action, method string, signedURL string, actualSignedRequestHeaders http.Header, data io.Reader, output IBaseModel, xmlResult bool) (respError error) { 224 req, err := http.NewRequest(method, signedURL, data) 225 if err != nil { 226 return err 227 } 228 if obsClient.conf.ctx != nil { 229 req = req.WithContext(obsClient.conf.ctx) 230 } 231 var resp *http.Response 232 233 var isSecurityToken bool 234 var securityToken string 235 var query []string 236 parmas := strings.Split(signedURL, "?") 237 if len(parmas) > 1 { 238 query = strings.Split(parmas[1], "&") 239 for _, value := range query { 240 if strings.HasPrefix(value, HEADER_STS_TOKEN_AMZ+"=") || strings.HasPrefix(value, HEADER_STS_TOKEN_OBS+"=") { 241 if value[len(HEADER_STS_TOKEN_AMZ)+1:] != "" { 242 securityToken = value[len(HEADER_STS_TOKEN_AMZ)+1:] 243 isSecurityToken = true 244 } 245 } 246 } 247 } 248 logSignedURL := signedURL 249 if isSecurityToken { 250 logSignedURL = strings.Replace(logSignedURL, securityToken, "******", -1) 251 } 252 doLog(LEVEL_INFO, "Do %s with signedUrl %s...", action, logSignedURL) 253 254 req.Header = actualSignedRequestHeaders 255 if value, ok := req.Header[HEADER_HOST_CAMEL]; ok { 256 req.Host = value[0] 257 delete(req.Header, HEADER_HOST_CAMEL) 258 } else if value, ok := req.Header[HEADER_HOST]; ok { 259 req.Host = value[0] 260 delete(req.Header, HEADER_HOST) 261 } 262 263 if value, ok := req.Header[HEADER_CONTENT_LENGTH_CAMEL]; ok { 264 req.ContentLength = StringToInt64(value[0], -1) 265 delete(req.Header, HEADER_CONTENT_LENGTH_CAMEL) 266 } else if value, ok := req.Header[HEADER_CONTENT_LENGTH]; ok { 267 req.ContentLength = StringToInt64(value[0], -1) 268 delete(req.Header, HEADER_CONTENT_LENGTH) 269 } 270 271 userAgent := prepareAgentHeader(obsClient.conf.userAgent) 272 req.Header[HEADER_USER_AGENT_CAMEL] = []string{userAgent} 273 start := GetCurrentTimestamp() 274 resp, err = obsClient.httpClient.Do(req) 275 if isInfoLogEnabled() { 276 doLog(LEVEL_INFO, "Do http request cost %d ms", (GetCurrentTimestamp() - start)) 277 } 278 279 respError = obsClient.getSignedURLResponse(action, output, xmlResult, resp, err, start) 280 281 return 282 } 283 284 func prepareData(headers map[string][]string, data interface{}) (io.Reader, error) { 285 var _data io.Reader 286 if data != nil { 287 if dataStr, ok := data.(string); ok { 288 doLog(LEVEL_DEBUG, "Do http request with string") 289 headers[HEADER_CONTENT_LENGTH_CAMEL] = []string{IntToString(len(dataStr))} 290 _data = strings.NewReader(dataStr) 291 } else if dataByte, ok := data.([]byte); ok { 292 doLog(LEVEL_DEBUG, "Do http request with byte array") 293 headers[HEADER_CONTENT_LENGTH_CAMEL] = []string{IntToString(len(dataByte))} 294 _data = bytes.NewReader(dataByte) 295 } else if dataReader, ok := data.(io.Reader); ok { 296 _data = dataReader 297 } else { 298 doLog(LEVEL_WARN, "Data is not a valid io.Reader") 299 return nil, errors.New("Data is not a valid io.Reader") 300 } 301 } 302 return _data, nil 303 } 304 305 func (obsClient ObsClient) getRequest(redirectURL, requestURL string, redirectFlag bool, _data io.Reader, method, 306 bucketName, objectKey string, params map[string]string, headers map[string][]string) (*http.Request, error) { 307 if redirectURL != "" { 308 if !redirectFlag { 309 parsedRedirectURL, err := url.Parse(redirectURL) 310 if err != nil { 311 return nil, err 312 } 313 requestURL, err = obsClient.doAuth(method, bucketName, objectKey, params, headers, parsedRedirectURL.Host) 314 if err != nil { 315 return nil, err 316 } 317 if parsedRequestURL, err := url.Parse(requestURL); err != nil { 318 return nil, err 319 } else if parsedRequestURL.RawQuery != "" && parsedRedirectURL.RawQuery == "" { 320 redirectURL += "?" + parsedRequestURL.RawQuery 321 } 322 } 323 requestURL = redirectURL 324 } else { 325 var err error 326 requestURL, err = obsClient.doAuth(method, bucketName, objectKey, params, headers, "") 327 if err != nil { 328 return nil, err 329 } 330 } 331 332 req, err := http.NewRequest(method, requestURL, _data) 333 if obsClient.conf.ctx != nil { 334 req = req.WithContext(obsClient.conf.ctx) 335 } 336 if err != nil { 337 return nil, err 338 } 339 doLog(LEVEL_DEBUG, "Do request with url [%s] and method [%s]", requestURL, method) 340 return req, nil 341 } 342 343 func logHeaders(headers map[string][]string, signature SignatureType) { 344 if isDebugLogEnabled() { 345 auth := headers[HEADER_AUTH_CAMEL] 346 delete(headers, HEADER_AUTH_CAMEL) 347 348 var isSecurityToken bool 349 var securityToken []string 350 if securityToken, isSecurityToken = headers[HEADER_STS_TOKEN_AMZ]; isSecurityToken { 351 headers[HEADER_STS_TOKEN_AMZ] = []string{"******"} 352 } else if securityToken, isSecurityToken = headers[HEADER_STS_TOKEN_OBS]; isSecurityToken { 353 headers[HEADER_STS_TOKEN_OBS] = []string{"******"} 354 } 355 doLog(LEVEL_DEBUG, "Request headers: %s", logRequestHeader(headers)) 356 headers[HEADER_AUTH_CAMEL] = auth 357 if isSecurityToken { 358 if signature == SignatureObs { 359 headers[HEADER_STS_TOKEN_OBS] = securityToken 360 } else { 361 headers[HEADER_STS_TOKEN_AMZ] = securityToken 362 } 363 } 364 } 365 } 366 367 func prepareReq(headers map[string][]string, req, lastRequest *http.Request, clientUserAgent string) *http.Request { 368 for key, value := range headers { 369 if key == HEADER_HOST_CAMEL { 370 req.Host = value[0] 371 delete(headers, key) 372 } else if key == HEADER_CONTENT_LENGTH_CAMEL { 373 req.ContentLength = StringToInt64(value[0], -1) 374 delete(headers, key) 375 } else { 376 req.Header[key] = value 377 } 378 } 379 380 lastRequest = req 381 382 userAgent := prepareAgentHeader(clientUserAgent) 383 req.Header[HEADER_USER_AGENT_CAMEL] = []string{userAgent} 384 385 if lastRequest != nil { 386 req.Host = lastRequest.Host 387 req.ContentLength = lastRequest.ContentLength 388 } 389 return lastRequest 390 } 391 392 func canNotRetry(repeatable bool, statusCode int) bool { 393 if !repeatable || (statusCode >= 400 && statusCode < 500) || statusCode == 304 { 394 return true 395 } 396 return false 397 } 398 399 func isRedirectErr(location string, redirectCount, maxRedirectCount int) bool { 400 if location != "" && redirectCount < maxRedirectCount { 401 return true 402 } 403 return false 404 } 405 406 func setRedirectFlag(statusCode int, method string) (redirectFlag bool) { 407 if statusCode == 302 && method == HTTP_GET { 408 redirectFlag = true 409 } else { 410 redirectFlag = false 411 } 412 return 413 } 414 415 func prepareRetry(resp *http.Response, headers map[string][]string, _data io.Reader, msg interface{}) (io.Reader, *http.Response, error) { 416 if resp != nil { 417 _err := resp.Body.Close() 418 checkAndLogErr(_err, LEVEL_WARN, "Failed to close resp body") 419 resp = nil 420 } 421 422 if _, ok := headers[HEADER_DATE_CAMEL]; ok { 423 headers[HEADER_DATE_CAMEL] = []string{FormatUtcToRfc1123(time.Now().UTC())} 424 } 425 426 if _, ok := headers[HEADER_DATE_AMZ]; ok { 427 headers[HEADER_DATE_AMZ] = []string{FormatUtcToRfc1123(time.Now().UTC())} 428 } 429 430 if _, ok := headers[HEADER_AUTH_CAMEL]; ok { 431 delete(headers, HEADER_AUTH_CAMEL) 432 } 433 doLog(LEVEL_WARN, "Failed to send request with reason:%v, will try again", msg) 434 if r, ok := _data.(*strings.Reader); ok { 435 _, err := r.Seek(0, 0) 436 if err != nil { 437 return nil, nil, err 438 } 439 } else if r, ok := _data.(*bytes.Reader); ok { 440 _, err := r.Seek(0, 0) 441 if err != nil { 442 return nil, nil, err 443 } 444 } else if r, ok := _data.(*fileReaderWrapper); ok { 445 fd, err := os.Open(r.filePath) 446 if err != nil { 447 return nil, nil, err 448 } 449 fileReaderWrapper := &fileReaderWrapper{filePath: r.filePath} 450 fileReaderWrapper.mark = r.mark 451 fileReaderWrapper.reader = fd 452 fileReaderWrapper.totalCount = r.totalCount 453 _data = fileReaderWrapper 454 _, err = fd.Seek(r.mark, 0) 455 if err != nil { 456 errMsg := fd.Close() 457 checkAndLogErr(errMsg, LEVEL_WARN, "Failed to close with reason: %v", errMsg) 458 return nil, nil, err 459 } 460 } else if r, ok := _data.(*readerWrapper); ok { 461 _, err := r.seek(0, 0) 462 if err != nil { 463 return nil, nil, err 464 } 465 r.readedCount = 0 466 } 467 return _data, resp, nil 468 } 469 470 // handleBody handles request body 471 func handleBody(req *http.Request, body io.Reader, listener ProgressListener, tracker *readerTracker) { 472 reader := body 473 if ret, ok := req.Header[HEADER_CONTENT_LENGTH_CAMEL]; !ok { 474 readerLen, err := GetReaderLen(reader) 475 if err == nil { 476 req.ContentLength = readerLen 477 } 478 if req.ContentLength > 0 { 479 req.Header.Set(HEADER_CONTENT_LENGTH_CAMEL, strconv.FormatInt(req.ContentLength, 10)) 480 } 481 } else { 482 req.ContentLength = StringToInt64(ret[0], 0) 483 } 484 485 if reader != nil { 486 reader = TeeReader(reader, req.ContentLength, listener, tracker) 487 } 488 489 // HTTP body 490 rc, ok := reader.(io.ReadCloser) 491 if !ok && reader != nil { 492 rc = ioutil.NopCloser(reader) 493 } 494 495 req.Body = rc 496 } 497 498 func (obsClient ObsClient) doHTTP(method, bucketName, objectKey string, params map[string]string, 499 headers map[string][]string, data interface{}, repeatable bool, listener ProgressListener) (resp *http.Response, respError error) { 500 defer func() { 501 _ = recover() 502 }() 503 bucketName = strings.TrimSpace(bucketName) 504 505 method = strings.ToUpper(method) 506 507 var redirectURL string 508 var requestURL string 509 maxRetryCount := obsClient.conf.maxRetryCount 510 maxRedirectCount := obsClient.conf.maxRedirectCount 511 512 _data, _err := prepareData(headers, data) 513 if _err != nil { 514 return nil, _err 515 } 516 517 var lastRequest *http.Request 518 redirectFlag := false 519 520 tracker := &readerTracker{completedBytes: 0} 521 522 for i, redirectCount := 0, 0; i <= maxRetryCount; i++ { 523 req, err := obsClient.getRequest(redirectURL, requestURL, redirectFlag, _data, 524 method, bucketName, objectKey, params, headers) 525 if err != nil { 526 return nil, err 527 } 528 529 handleBody(req, _data, listener, tracker) 530 531 logHeaders(headers, obsClient.conf.signature) 532 533 lastRequest = prepareReq(headers, req, lastRequest, obsClient.conf.userAgent) 534 535 // Transfer started 536 event := newProgressEvent(TransferStartedEvent, 0, req.ContentLength) 537 publishProgress(listener, event) 538 539 start := GetCurrentTimestamp() 540 isObs := obsClient.conf.signature == SignatureObs 541 resp, err = obsClient.httpClient.Do(req) 542 doLog(LEVEL_INFO, "Do http request cost %d ms", (GetCurrentTimestamp() - start)) 543 544 var msg interface{} 545 if err != nil { 546 msg = err 547 respError = err 548 resp = nil 549 if !repeatable { 550 break 551 } 552 } else { 553 doLog(LEVEL_DEBUG, "Response headers: %s", logResponseHeader(resp.Header)) 554 if resp.StatusCode < 300 { 555 event := newProgressEvent(TransferCompletedEvent, tracker.completedBytes, req.ContentLength) 556 publishProgress(listener, event) 557 respError = nil 558 break 559 } else if canNotRetry(repeatable, resp.StatusCode) { 560 event = newProgressEvent(TransferFailedEvent, tracker.completedBytes, req.ContentLength) 561 publishProgress(listener, event) 562 563 respError = ParseResponseToObsError(resp, isObs) 564 resp = nil 565 break 566 } else if resp.StatusCode >= 300 && resp.StatusCode < 400 { 567 location := resp.Header.Get(HEADER_LOCATION_CAMEL) 568 if isRedirectErr(location, redirectCount, maxRedirectCount) { 569 redirectURL = location 570 doLog(LEVEL_WARN, "Redirect request to %s", redirectURL) 571 msg = resp.Status 572 maxRetryCount++ 573 redirectCount++ 574 redirectFlag = setRedirectFlag(resp.StatusCode, method) 575 } else { 576 respError = ParseResponseToObsError(resp, isObs) 577 resp = nil 578 break 579 } 580 } else { 581 msg = resp.Status 582 } 583 } 584 if i != maxRetryCount { 585 _data, resp, err = prepareRetry(resp, headers, _data, msg) 586 if err != nil { 587 return nil, err 588 } 589 if r, ok := _data.(*fileReaderWrapper); ok { 590 if _fd, _ok := r.reader.(*os.File); _ok { 591 defer func() { 592 errMsg := _fd.Close() 593 checkAndLogErr(errMsg, LEVEL_WARN, "Failed to close with reason: %v", errMsg) 594 }() 595 } 596 } 597 time.Sleep(time.Duration(float64(i+2) * rand.Float64() * float64(time.Second))) 598 } else { 599 doLog(LEVEL_ERROR, "Failed to send request with reason:%v", msg) 600 if resp != nil { 601 respError = ParseResponseToObsError(resp, isObs) 602 resp = nil 603 } 604 event = newProgressEvent(TransferFailedEvent, tracker.completedBytes, req.ContentLength) 605 publishProgress(listener, event) 606 } 607 } 608 return 609 } 610 611 type connDelegate struct { 612 conn net.Conn 613 socketTimeout time.Duration 614 finalTimeout time.Duration 615 } 616 617 func getConnDelegate(conn net.Conn, socketTimeout int, finalTimeout int) *connDelegate { 618 return &connDelegate{ 619 conn: conn, 620 socketTimeout: time.Second * time.Duration(socketTimeout), 621 finalTimeout: time.Second * time.Duration(finalTimeout), 622 } 623 } 624 625 func (delegate *connDelegate) Read(b []byte) (n int, err error) { 626 setReadDeadlineErr := delegate.SetReadDeadline(time.Now().Add(delegate.socketTimeout)) 627 flag := isDebugLogEnabled() 628 629 if setReadDeadlineErr != nil && flag { 630 doLog(LEVEL_DEBUG, "Failed to set read deadline with reason: %v, but it's ok", setReadDeadlineErr) 631 } 632 633 n, err = delegate.conn.Read(b) 634 setReadDeadlineErr = delegate.SetReadDeadline(time.Now().Add(delegate.finalTimeout)) 635 if setReadDeadlineErr != nil && flag { 636 doLog(LEVEL_DEBUG, "Failed to set read deadline with reason: %v, but it's ok", setReadDeadlineErr) 637 } 638 return n, err 639 } 640 641 func (delegate *connDelegate) Write(b []byte) (n int, err error) { 642 setWriteDeadlineErr := delegate.SetWriteDeadline(time.Now().Add(delegate.socketTimeout)) 643 flag := isDebugLogEnabled() 644 if setWriteDeadlineErr != nil && flag { 645 doLog(LEVEL_DEBUG, "Failed to set write deadline with reason: %v, but it's ok", setWriteDeadlineErr) 646 } 647 648 n, err = delegate.conn.Write(b) 649 finalTimeout := time.Now().Add(delegate.finalTimeout) 650 setWriteDeadlineErr = delegate.SetWriteDeadline(finalTimeout) 651 if setWriteDeadlineErr != nil && flag { 652 doLog(LEVEL_DEBUG, "Failed to set write deadline with reason: %v, but it's ok", setWriteDeadlineErr) 653 } 654 setReadDeadlineErr := delegate.SetReadDeadline(finalTimeout) 655 if setReadDeadlineErr != nil && flag { 656 doLog(LEVEL_DEBUG, "Failed to set read deadline with reason: %v, but it's ok", setReadDeadlineErr) 657 } 658 return n, err 659 } 660 661 func (delegate *connDelegate) Close() error { 662 return delegate.conn.Close() 663 } 664 665 func (delegate *connDelegate) LocalAddr() net.Addr { 666 return delegate.conn.LocalAddr() 667 } 668 669 func (delegate *connDelegate) RemoteAddr() net.Addr { 670 return delegate.conn.RemoteAddr() 671 } 672 673 func (delegate *connDelegate) SetDeadline(t time.Time) error { 674 return delegate.conn.SetDeadline(t) 675 } 676 677 func (delegate *connDelegate) SetReadDeadline(t time.Time) error { 678 return delegate.conn.SetReadDeadline(t) 679 } 680 681 func (delegate *connDelegate) SetWriteDeadline(t time.Time) error { 682 return delegate.conn.SetWriteDeadline(t) 683 }